import logging
from pathlib import Path
import cnvpytor
from openanno_cnv import Annotation

from .utils import is_active_chrom


logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
logger = logging.getLogger("ClinCNVseq")


class VCF(Annotation):
    sample: str
    app: cnvpytor.Root
    bin_size: int
    call_vcf_file: Path
    vcf_file: Path
    gender: str

    class Config:
        arbitrary_types_allowed = True

    @classmethod
    def calc_filter(cls, q0: float, pn: float) -> str:
        flags = list()
        if q0 > 0.5:
            flags.append("Q0gt0.5")
        if pn > 0.5:
            flags.append("PNgt0.5")
        return ";".join(flags) or "PASS"

    def export_vcf(self):
        logger.info("Do call VCF to %s", self.call_vcf_file)
        calls = self.app.call([self.bin_size], use_mask=True)
        with open(self.call_vcf_file, "w") as writer:
            writer.write("##fileformat=VCFv4.2\n")
            writer.write('##INFO=<ID=END,Number=1,Type=Integer,Description="End Position">\n')
            writer.write('##INFO=<ID=SVTYPE,Number=1,Type=String,Description="SV Type">\n')
            writer.write('##FORMAT=<ID=CN,Number=1,Type=Float,Description="Copy Number">\n')
            writer.write('##FORMAT=<ID=LEVEL,Number=1,Type=Float,Description="Level">\n')
            writer.write(
                '##FORMAT=<ID=E1,Number=1,Type=Float,Description="e-value (p-value multiplied by genome size divided by bin size) calculated using t-test statistics between RD statistics in the region and global">\n'
            )
            writer.write(
                '##FORMAT=<ID=E2,Number=1,Type=Float,Description="e-value (p-value multiplied by genome size divided by bin size) from the probability of RD values within the region to be in the tails of a gaussian distribution of binned RD">\n'
            )
            writer.write('##FORMAT=<ID=E3,Number=1,Type=Float,Description="same as e-val1 but for the middle of CNV">\n')
            writer.write('##FORMAT=<ID=E4,Number=1,Type=Float,Description="same as e-val2 but for the middle of CNV">\n')
            writer.write('##FORMAT=<ID=Q0,Number=1,Type=Float,Description="fraction of reads mapped with q0 quality in call region">\n')
            writer.write('##FORMAT=<ID=PN,Number=1,Type=Float,Description="fraction of reference genome gaps (Ns) in call region">\n')
            writer.write('##FORMAT=<ID=DG,Number=1,Type=Float,Description="distance from closest large (>100bp) gap in reference genome">\n')
            writer.write('##FILTER=<ID=Q0gt0.5,Description="Q0 greater than 0.5">\n')
            writer.write('##FILTER=<ID=PNgt0.5,Description="PN greater than 0.5">\n')
            writer.write("##source=CNVpytor\n")
            writer.write(f"#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\tFORMAT\t{self.sample}\n")
            for bin_size, bin_calls in calls.items():
                logger.info("Writing CNV with bin size: %d", bin_size)
                for alt, chrom, start, end, _, level, e1, e2, e3, e4, q0, pn, dg in bin_calls:
                    if is_active_chrom(chrom, self.gender):
                        filter_text = self.calc_filter(q0, pn)
                        info_text = f"END={end};SVTYPE={alt}"
                        format_text = f"CN:LEVEL:E1:E2:E3:E4:Q0:PN:DG\t{level*2}:{level}:{e1}:{e2}:{e3}:{e4}:{q0}:{pn}:{dg}"
                        writer.write(f"{chrom}\t{start}\t.\t<DIP>\t<{alt[0:3].upper()}>\t.\t{filter_text}\t{info_text}\t{format_text}\n")

    def do_vcf(self):
        logger.info("Do VCF to %s", self.vcf_file)
        self.do_annotation(
            input_file=self.call_vcf_file,
            output_file=self.vcf_file,
        )

    def run(self):
        if not self.call_vcf_file.exists():
            self.export_vcf()
        if not self.vcf_file.exists():
            self.do_vcf()
